"""
姿态检测相关的数据模型定义
"""
from datetime import datetime
from typing import List, Dict, Any, Optional, Tuple
from pydantic import BaseModel, Field, field_validator
from enum import Enum
import numpy as np


class PoseModel(str, Enum):
    """姿态模型枚举"""
    MEDIAPIPE = "mediapipe"
    OPENPOSE = "openpose"
    YOLO_POSE = "yolo_pose"
    HRNET = "hrnet"


class JointType(str, Enum):
    """关节点类型枚举"""
    NOSE = "nose"
    LEFT_EYE = "left_eye"
    RIGHT_EYE = "right_eye"
    LEFT_EAR = "left_ear"
    RIGHT_EAR = "right_ear"
    LEFT_SHOULDER = "left_shoulder"
    RIGHT_SHOULDER = "right_shoulder"
    LEFT_ELBOW = "left_elbow"
    RIGHT_ELBOW = "right_elbow"
    LEFT_WRIST = "left_wrist"
    RIGHT_WRIST = "right_wrist"
    LEFT_HIP = "left_hip"
    RIGHT_HIP = "right_hip"
    LEFT_KNEE = "left_knee"
    RIGHT_KNEE = "right_knee"
    LEFT_ANKLE = "left_ankle"
    RIGHT_ANKLE = "right_ankle"


class ActionType(str, Enum):
    """动作类型枚举"""
    STANDING = "standing"
    WALKING = "walking"
    RUNNING = "running"
    SITTING = "sitting"
    LYING = "lying"
    JUMPING = "jumping"
    WAVING = "waving"
    POINTING = "pointing"
    FIGHTING = "fighting"
    PUSHING = "pushing"
    FALLING = "falling"
    RAISING_HAND = "raising_hand"
    CLAPPING = "clapping"
    UNKNOWN = "unknown"


class BehaviorSeverity(str, Enum):
    """行为严重程度枚举"""
    NORMAL = "normal"
    SUSPICIOUS = "suspicious"
    CONCERNING = "concerning"
    DANGEROUS = "dangerous"
    CRITICAL = "critical"


class Keypoint(BaseModel):
    """关节点模型"""
    joint_type: JointType = Field(..., description="关节点类型")
    x: float = Field(..., description="X坐标")
    y: float = Field(..., description="Y坐标")
    confidence: float = Field(..., ge=0, le=1, description="置信度")
    visibility: Optional[float] = Field(None, ge=0, le=1, description="可见性")
    
    model_config = {
        "json_schema_extra": {
            "example": {
                "joint_type": "left_shoulder",
                "x": 150.5,
                "y": 200.3,
                "confidence": 0.95,
                "visibility": 0.8
            }
        }
    }


class PoseEstimation(BaseModel):
    """姿态估计结果模型"""
    pose_id: str = Field(..., description="姿态ID")
    person_id: str = Field(..., description="人员ID")
    keypoints: List[Keypoint] = Field(..., description="关节点列表")
    bbox: List[float] = Field(..., description="边界框 [x1, y1, x2, y2]")
    pose_confidence: float = Field(..., ge=0, le=1, description="整体姿态置信度")
    timestamp: datetime = Field(..., description="检测时间")
    model_used: PoseModel = Field(..., description="使用的模型")
    
    @field_validator('bbox')
    @classmethod
    def validate_bbox(cls, v: List[float]) -> List[float]:
        if len(v) != 4:
            raise ValueError('边界框必须包含4个值: [x1, y1, x2, y2]')
        return v
    
    def get_keypoint(self, joint_type: JointType) -> Optional[Keypoint]:
        """获取指定关节点"""
        for keypoint in self.keypoints:
            if keypoint.joint_type == joint_type:
                return keypoint
        return None
    
    def get_center_point(self) -> Tuple[float, float]:
        """获取姿态中心点"""
        valid_keypoints = [kp for kp in self.keypoints if kp.confidence > 0.5]
        if not valid_keypoints:
            return (0, 0)
        
        center_x = sum(kp.x for kp in valid_keypoints) / len(valid_keypoints)
        center_y = sum(kp.y for kp in valid_keypoints) / len(valid_keypoints)
        return (center_x, center_y)
    
    model_config = {
        "json_schema_extra": {
            "example": {
                "pose_id": "pose_123456",
                "person_id": "person_001",
                "keypoints": [],
                "bbox": [100, 100, 200, 300],
                "pose_confidence": 0.92,
                "timestamp": "2024-01-01T12:00:00Z",
                "model_used": "mediapipe"
            }
        }}


class ActionRecognition(BaseModel):
    """动作识别结果模型"""
    action_id: str = Field(..., description="动作ID")
    person_id: str = Field(..., description="人员ID")
    action_type: ActionType = Field(..., description="动作类型")
    confidence: float = Field(..., ge=0, le=1, description="置信度")
    start_time: datetime = Field(..., description="动作开始时间")
    end_time: Optional[datetime] = Field(None, description="动作结束时间")
    duration: Optional[float] = Field(None, description="持续时间(秒)")
    pose_sequence: List[str] = Field([], description="姿态序列ID列表")
    features: Dict[str, float] = Field({}, description="动作特征")
    severity: BehaviorSeverity = Field(BehaviorSeverity.NORMAL, description="严重程度")
    
    def get_duration(self) -> float:
        """计算动作持续时间"""
        if self.end_time:
            return (self.end_time - self.start_time).total_seconds()
        return 0.0
    
    model_config = {"json_schema_extra": {
            "example": {
                "action_id": "action_789",
                "person_id": "person_001",
                "action_type": "walking",
                "confidence": 0.88,
                "start_time": "2024-01-01T12:00:00Z",
                "end_time": "2024-01-01T12:00:05Z",
                "duration": 5.0,
                "pose_sequence": ["pose_123", "pose_124", "pose_125"],
                "features": {
                "speed": 1.2,
                "smoothness": 0.8
                },
                "severity": "normal"
            }}
        }


class BehaviorPattern(BaseModel):
    """行为模式模型"""
    pattern_id: str = Field(..., description="模式ID")
    pattern_name: str = Field(..., description="模式名称")
    action_sequence: List[ActionType] = Field(..., description="动作序列")
    temporal_constraints: Dict[str, Any] = Field({}, description="时间约束")
    spatial_constraints: Dict[str, Any] = Field({}, description="空间约束")
    confidence_threshold: float = Field(0.7, ge=0, le=1, description="置信度阈值")
    severity: BehaviorSeverity = Field(..., description="严重程度")
    description: str = Field("", description="模式描述")
    
    model_config = {
        "json_schema_extra": {
            "example": {
                "pattern_id": "pattern_fighting",
                "pattern_name": "打架行为模式",
                "action_sequence": ["pushing", "fighting"],
                "temporal_constraints": {
                "max_interval": 5.0,
                "min_duration": 2.0
                },
                "spatial_constraints": {
                "max_distance": 100.0
                }},
                "confidence_threshold": 0.8,
                "severity": "dangerous",
                "description": "检测推搡后的打架行为"
            }
        }


class PoseAnalysisResult(BaseModel):
    """姿态分析结果模型"""
    analysis_id: str = Field(..., description="分析ID")
    camera_id: str = Field(..., description="摄像头ID")
    timestamp: datetime = Field(..., description="分析时间")
    poses: List[PoseEstimation] = Field(..., description="检测到的姿态列表")
    actions: List[ActionRecognition] = Field(..., description="识别到的动作列表")
    behavior_patterns: List[Dict[str, Any]] = Field([], description="匹配的行为模式")
    total_persons: int = Field(..., description="总人数")
    processing_time: float = Field(..., description="处理时间(秒)")
    model_info: Dict[str, Any] = Field({}, description="模型信息")
    
    model_config = {
        "json_schema_extra": {
            "example": {
                "analysis_id": "analysis_456",
                "camera_id": "cam_001",
                "timestamp": "2024-01-01T12:00:00Z",
                "poses": [],
                "actions": [],
                "behavior_patterns": [],
                "total_persons": 3,
                "processing_time": 0.25,
                "model_info": {
                "pose_model": "mediapipe",
                "action_model": "lstm_classifier"
            }
            }}
        }


class PoseConfig(BaseModel):
    """姿态检测配置模型"""
    model_type: PoseModel = Field(PoseModel.MEDIAPIPE, description="姿态模型类型")
    confidence_threshold: float = Field(0.5, ge=0, le=1, description="置信度阈值")
    min_detection_confidence: float = Field(0.5, ge=0, le=1, description="最小检测置信度")
    min_tracking_confidence: float = Field(0.5, ge=0, le=1, description="最小跟踪置信度")
    max_num_poses: int = Field(10, ge=1, description="最大检测姿态数")
    enable_segmentation: bool = Field(False, description="是否启用分割")
    smooth_landmarks: bool = Field(True, description="是否平滑关键点")
    static_image_mode: bool = Field(False, description="静态图像模式")
    
    model_config = {
        "json_schema_extra": {
            "example": {
                "model_type": "mediapipe",
                "confidence_threshold": 0.7,
                "min_detection_confidence": 0.5,
                "min_tracking_confidence": 0.5,
                "max_num_poses": 5,
                "enable_segmentation": False,
                "smooth_landmarks": True,
                "static_image_mode": False
            }
        }}


class ActionConfig(BaseModel):
    """动作识别配置模型"""
    sequence_length: int = Field(30, ge=5, description="序列长度")
    overlap_ratio: float = Field(0.5, ge=0, le=1, description="重叠比例")
    confidence_threshold: float = Field(0.6, ge=0, le=1, description="置信度阈值")
    temporal_smoothing: bool = Field(True, description="时间平滑")
    feature_normalization: bool = Field(True, description="特征归一化")
    enable_pattern_matching: bool = Field(True, description="启用模式匹配")
    
    model_config = {"json_schema_extra": {
            "example": {
                "sequence_length": 30,
                "overlap_ratio": 0.5,
                "confidence_threshold": 0.7,
                "temporal_smoothing": True,
                "feature_normalization": True,
                "enable_pattern_matching": True
        }
    }
        }


class PoseTrackingInfo(BaseModel):
    """姿态跟踪信息模型"""
    track_id: str = Field(..., description="跟踪ID")
    person_id: str = Field(..., description="人员ID")
    pose_history: List[str] = Field([], description="姿态历史ID列表")
    action_history: List[str] = Field([], description="动作历史ID列表")
    start_time: datetime = Field(..., description="开始跟踪时间")
    last_update: datetime = Field(..., description="最后更新时间")
    is_active: bool = Field(True, description="是否活跃")
    tracking_quality: float = Field(1.0, ge=0, le=1, description="跟踪质量")
    
    model_config = {
        "json_schema_extra": {
            "example": {
                "track_id": "track_pose_001",
                "person_id": "person_001",
                "pose_history": ["pose_123", "pose_124", "pose_125"],
                "action_history": ["action_456", "action_457"],
                "start_time": "2024-01-01T12:00:00Z",
                "last_update": "2024-01-01T12:00:30Z",
                "is_active": True,
                "tracking_quality": 0.95
            }
        }}


class BehaviorAlert(BaseModel):
    """行为告警模型"""
    alert_id: str = Field(..., description="告警ID")
    camera_id: str = Field(..., description="摄像头ID")
    person_ids: List[str] = Field(..., description="涉及人员ID列表")
    behavior_type: str = Field(..., description="行为类型")
    severity: BehaviorSeverity = Field(..., description="严重程度")
    confidence: float = Field(..., ge=0, le=1, description="置信度")
    description: str = Field(..., description="告警描述")
    evidence: Dict[str, Any] = Field({}, description="证据信息")
    timestamp: datetime = Field(..., description="告警时间")
    location: Optional[List[float]] = Field(None, description="位置信息")
    duration: Optional[float] = Field(None, description="持续时间")
    resolved: bool = Field(False, description="是否已解决")
    
    model_config = {"json_schema_extra": {
            "example": {
                "alert_id": "alert_behavior_001",
                "camera_id": "cam_001",
                "person_ids": ["person_001", "person_002"],
                "behavior_type": "fighting",
                "severity": "dangerous",
                "confidence": 0.92,
                "description": "检测到打架行为",
                "evidence": {
                "action_sequence": ["pushing", "fighting"],
                "duration": 8.5,
                "max_confidence": 0.95
                },
                "timestamp": "2024-01-01T12:00:00Z",
                "location": [320, 240],
                "duration": 8.5,
                "resolved": False
            }}
        }


class ModelPerformance(BaseModel):
    """模型性能指标模型"""
    model_name: str = Field(..., description="模型名称")
    model_type: str = Field(..., description="模型类型")
    total_inferences: int = Field(0, description="总推理次数")
    successful_inferences: int = Field(0, description="成功推理次数")
    failed_inferences: int = Field(0, description="失败推理次数")
    average_inference_time: float = Field(0.0, description="平均推理时间(毫秒)")
    average_confidence: float = Field(0.0, description="平均置信度")
    accuracy_metrics: Optional[Dict[str, float]] = Field(None, description="准确率指标")
    last_updated: datetime = Field(..., description="最后更新时间")
    
    model_config = {
        "json_schema_extra": {
            "example": {
                "model_name": "MediaPipe Pose",
                "model_type": "pose_estimation",
                "total_inferences": 5000,
                "successful_inferences": 4950,
                "failed_inferences": 50,
                "average_inference_time": 25.5,
                "average_confidence": 0.87,
                "accuracy_metrics": {
                "precision": 0.92,
                "recall": 0.89,
                "f1_score": 0.90
                },
                "last_updated": "2024-01-01T12:00:00Z"
            }}
        }